package com.hummer.browser;

import java.io.File;
import java.util.Map;

import org.openqa.selenium.Cookie;
import org.openqa.selenium.MutableCapabilities;
import org.openqa.selenium.Platform;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.remote.service.DriverService;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;

public abstract class AbstractBrowser implements Browser {

	protected WebDriver driver = null;
	protected BrowserContext context = null;
	protected BrowserConfig<?> bconfig = null;

	public AbstractBrowser(BrowserConfig<?> config) {
		initialize(config);
	}

	public void initialize(BrowserConfig<?> config) {
		bconfig = config;
		int port = bconfig.generateId().usingFreePort().getPort();
		String exepath = bconfig.getExecuteFile();
		File exe = new File(exepath);
		ImmutableList<String> args = bconfig.createArgs();
		ImmutableMap<String, String> envs = bconfig.createEnv();
		MutableCapabilities options = bconfig.createOptions();
		DriverService ds = createDefaultDriverService(exe, port, args, envs);
		driver = initDriver(ds, options);
		context = initContext();
	}

	protected abstract DriverService createDefaultDriverService(File exe, int port, ImmutableList<String> args,
			ImmutableMap<String, String> env);

	protected abstract WebDriver initDriver(DriverService ds, MutableCapabilities op);

	protected BrowserContext initContext() {
		synchronized (this) {
			if (context == null) {
				context = new BrowserContext();
				context.setBrowser(this);
				context.setDriver(driver);
				context.setConfig(bconfig);
				context.setPort(bconfig.getPort());
				context.setId(bconfig.getId());
				context.setOs(Platform.getCurrent());
				context.setPage(new DocumentPage());
			}
			return context;
		}
	}

	public BrowserContext getContext() {
		return context;
	}

	public void reset() {
		String[] windows = getWindows();

		for (int i = 0; i < windows.length - 1; i++) {
			driver.switchTo().window(windows[i]);
			driver.manage().deleteAllCookies();
			driver.close();
		}
		driver.switchTo().window(windows[windows.length - 1]);
		driver.manage().deleteAllCookies();
		driver.navigate().to("about:blank");
	}

	// 关闭所有窗口，初始化浏览器
	public void close() {
		reset();
	}

	public void destory() {
		driver.quit();
	}

	private void forceDestory() {
		destory();
	}

	public Page get(String url, Cookie[] cookies) {
		for(Cookie cookie : cookies) {
			driver.manage().addCookie(cookie);
		}
		driver.get(url);
		return null;
	}

	public void closeWindow() {
		String[] windows = getWindows();
		if (windows.length > 1) {
			driver.close();
		} else if (windows.length == 1) {
			reset();
		}

	}

	public Page switchWindow(String window) {
		driver.switchTo().window(window);
		return null;
	}

	public Page switchWindowByUrl(String url) {
		return null;
	}

	public void closeWindow(String window) {
		String[] windows = getWindows();
		for (String w : windows) {
			if (w.equals(window)) {
				driver.switchTo().window(window);
				closeWindow();
			}
		}
	}

	public String[] getWindows() {
		return (String[]) driver.getWindowHandles().toArray();

	}

	public String getWindow() {
		return driver.getWindowHandle();

	}

	public void addCookie(Cookie cookie) {
		driver.manage().addCookie(cookie);

	}

	public void deleteCookieNamed(String cookieName) {
		driver.manage().deleteCookieNamed(cookieName);

	}

	public void deleteCookie(Cookie cookie) {
		driver.manage().deleteCookie(cookie);

	}

	public void deleteBrowserCookies() {
		String[] windows = this.getWindows();
		for (String window : windows) {
			driver.switchTo().window(window);
			driver.manage().deleteAllCookies();
		}

	}

	public void deleteDomainCookies() {
		driver.manage().deleteAllCookies();
	}

	// 切换当前所在Iframe Document域
	public Page switchIframe(String selector) {
		return null;
	}

	// 跳出当前所在的iframe document域 返回外层Page
	public Page closeIframe() {
		return null;
	}

	// 单击元素
	public Page click(String selector) {
		return null;
	}

	// 输入数据
	public void input(String selector, String text) {

	}

	// select标签选择
	public void select(String selector, String value) {

	}

	// 获取当前网页快照图像
	public byte[] snapshot() {
		return null;
	}

	// 获取元素相关布局信息
	public Rectangle getLayout(String selector) {
		return null;
	}

}
